<template>
    <el-row type="flex" align="middle">
        <table class="calendar-table">
            <thead class="calendar-head">
                <tr>
                    <th rowspan="8" id="timeHeader" class="week-td">星期/时间</th>
                    <th colspan="24">00:00 - 12:00</th>
                    <th colspan="24">12:00 - 24:00</th>
                </tr>
                <tr>
                    <td colspan="2" v-for="(hour,index) in hours" :key="index">{{index}}</td>
                </tr>
            </thead>
            <tbody class="calendar-body" v-drag>
                <tr v-for="time in times" :key="time.id">
                    <td width="75">{{time.week}}</td>
                    <td v-for="atom in time.atoms" :key="atom.id" :x="atom.id" :y="time.id" :data="getData(time.id, atom.id)">
                        <el-tooltip placement="top" :open-delay="500" :enterable="false">
                            <div slot="content">{{formatTip(time.id, atom.id)}}</div>
                            <el-row type="flex" class="selectTimeBlock" justify="center" align="middle" :class="isSelect(time.id, atom.id)" style="min-width: 11px;height: 30px;">
                                {{atom.text}}</el-row>
                        </el-tooltip>
                    </td>
                </tr>
                <tr>
                    <td colspan="49" class="td-table-tip">
                        <el-row type="flex" justify="space-between" class="clearfix">
                            <span class="pull-left tip-text">已选择时间段</span>
                            <el-button @click="clear" type="text" style="padding:0">清空</el-button>
                        </el-row>
                        <div class="td-selected-time">
                            <p v-for="selecTime in selecTimes" :key="selecTime.id">
                                <span class="tip-text">{{selecTime.weeks}}</span>
                                <span v-for="point in selecTime.points" :key="point.id">{{point.time}}、</span></p>
                        </div>
                    </td>
                </tr>
            </tbody>
        </table>
    </el-row>
</template>
<style>
    .calendar-table {
        border-collapse: collapse;
        border-radius: 4px;
        max-width: 652px;
        margin-top: 20px;
        position: relative;
    }

    .calendar-table tr,
    .calendar-table td,
    .calendar-table th {
        border: 1px solid #E4E9ED;
        font-size: 12px;
        text-align: center;
        min-width: 11px;
        line-height: 30px;
        -webkit-transition: background 200ms ease;
        -moz-transition: background 200ms ease;
        -ms-transition: background 200ms ease;
        transition: background 200ms ease;
    }

    .calendar-table thead th,
    .calendar-table thead td {
        background: #F8F9FA;
    }

    .calendar-table tbody tr td:first-child {
        background: #F8F9FA;
    }
    .calendar-table tr td:first-child{
        -moz-user-select:none;
        -webkit-user-select:none;
        user-select:none;
    }
    .calendar-table .td-table-tip {
        line-height: 2.4em;
        padding: 0 12px 0 19px;
        background: #fff !important;
        -moz-user-select:none;
        -webkit-user-select:none;
        user-select:none;
    }

    .calendar-table .td-table-tip .clearfix {
        margin: 10px 0 0 0;
    }

    .calendar-table .tip-text {
        color: #999;
        margin-right: 8px;
    }

    .calendar-table .td-table-tip .pull-left {
        font-size: 14px;
        color: #333333;
    }

    .calendar-table .td-selected-time {
        text-align: left;
        line-height: 2.4em;
    }

    .calendar-table .td-selected-time span {
        font-size: 13px;
    }
    .calendar-table .selected {
        background-color:#409EFF;
    }
</style>
<script>
    const COLUMN_COUNT = 48
    let atomdata = [];
    for (let i = 1; i <= COLUMN_COUNT; i++) {
        atomdata.push({
            "id": i,
            "text": ""
        });
    }
    let WEEKS = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日']
    export default {
        name: 'TimePicker',
        props: ['schedule_time'],
        model: {
            prop: 'schedule_time',
            event: 'change'
        },
        // 框选的指令
        directives: {
            drag: {
                // 指令的定义
                inserted: function (el, binding, vnode) {
                    var oDiv = el;
                    //监听用户鼠标事件
                    oDiv.onmousedown = function () {
                        //初始化不显示
                        vnode.context.toggleShow=false;  
                        //确保用户在移动鼠标的时候只初始化一次选中
                        //获得指令下的dom对应的表格
                        var fileNodes = oDiv.getElementsByTagName("td");    
                        //获得鼠标
                        var evt = window.event || arguments[0];
                        var startX = (evt.x || evt.clientX);
                        var startY = (evt.y || evt.clientY);
                        var top,left;
                        //时时获得
                        top=getY(oDiv);
                        left=getX(oDiv);
                        var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
                        var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
                        startX = startX + scrollX
                        startY = startY + scrollY
                        var spanX = 75
                        var spanY = 62
                        let timeHeader = oDiv.parentElement.querySelector("#timeHeader") //this.$refs.timeHeader
                        // console.log('====obj===', timeHeader, timeHeader.clientWidth, timeHeader.clientHeight)
                        spanX = timeHeader.clientWidth + 1
                        spanY = timeHeader.clientHeight + 1
                        
                        // console.log('鼠标位置', startX, startY, '组件画面位置', left, top, '计算位置', startX - left - spanX, startY-top)
                        var posX = startX - left
                        var posY = startY - top  + spanY
                        if (posX <= spanX) {
                            // 拉的外面直接跳过
                            console.log('not reponse area')
                            return
                        }

                        
                        // for (var i = 0; i < fileNodes.length; i++) {
                        //     var sl = fileNodes[i].offsetWidth + fileNodes[i].offsetLeft;
                        //     var st = fileNodes[i].offsetHeight + fileNodes[i].offsetTop;
                        //     // console.log(posX, posY, 'rect', fileNodes[i].offsetLeft, sl, fileNodes[i].offsetTop, sl,'数据', fileNodes[i].getAttribute('x'), fileNodes[i].getAttribute('y'))
                        //     if (posX > fileNodes[i].offsetLeft && posX < sl && posY > fileNodes[i].offsetTop && posY < st) {
                        //         // console.log('选中')
                        //         fileNodes[i].setAttribute('class', 'selected')
                        //         selList.push(fileNodes[i])
                        //     }
                        // }
                        var selDiv = document.createElement("div");
                        selDiv.style.cssText = "position:absolute;width:0px;height:0px;font-size:0px;margin:0px;padding:0px;border:1px dashed #0099FF;background-color:#C3D5ED;z-index:1000;filter:alpha(opacity:60);opacity:0.6;display:none;";
                        selDiv.id = "selectDiv";
                        document.getElementsByClassName("calendar-body")[0].appendChild(selDiv);
                        // selDiv.style.left = startX + "px";
                        // selDiv.style.top = startY + "px";
                        selDiv.style.left = posX + "px";
                        selDiv.style.top = posY + "px";
                        // console.log('startX', startX, 'startY', startY)
                        var _x = null;
                        var _y = null;
                        vnode.context.clearEventBubble(evt);
                        // //打开开关
                        vnode.context.mouseflag = true;
                        // //鼠标拖动时画框
                        document.onmousemove = function () {
                            evt = window.event || arguments[0];
                            _x = (evt.x || evt.clientX);
                            _y = (evt.y || evt.clientY);
                            _x = _x + scrollX
                            _y = _y + scrollY
                            //为了确定是点击事件还是移动事件
                            if(Math.abs(_x - startX)<5 && Math.abs(_y - startY)<5){
                                return;
                            }
                            //为了确保只有一次的渲染每次框选都把默认选中为空
                            // if(flag){
                            //     //重置选中css
                            //     for (var i = 0; i < fileNodes.length; i++) {
                            //         if (fileNodes[i].className.indexOf("el-table__row") != -1) {
                            //             fileNodes[i].className = "el-table__row";
                            //             selList.push(fileNodes[i]);
                            //         }
                            //     }     
                            //     vnode.context.multipleSelection=[]
                            //     vnode.context.tableData.forEach((ele)=>{
                            //         vnode.context.$refs.table.toggleRowSelection(ele,false)
                            //     })
                            //     flag = false;
                            // }
                            if (vnode.context.mouseflag) {
                                if (selDiv.style.display == "none") {
                                    selDiv.style.display = "";
                                }
                                // 计算出接近点再操作
                                let oneW = fileNodes[1].offsetWidth
                                let oneH = fileNodes[1].offsetHeight
                                for (var i = 0; i < fileNodes.length; i++) {
                                    var sl = fileNodes[i].offsetWidth + fileNodes[i].offsetLeft;
                                    var st = fileNodes[i].offsetHeight + fileNodes[i].offsetTop;
                                    // console.log(posX, posY, 'rect', fileNodes[i].offsetLeft, sl, fileNodes[i].offsetTop, sl,'数据', fileNodes[i].getAttribute('x'), fileNodes[i].getAttribute('y'))
                                    if (posX > fileNodes[i].offsetLeft && posX < sl && posY > fileNodes[i].offsetTop && posY < st) {
                                        posX = fileNodes[i].offsetLeft
                                        posY = fileNodes[i].offsetTop
                                        break
                                    }
                                }
                                let newLeft = 0
                                let newTop = 0
                                let newWidth = Math.abs(_x - startX)
                                let newHeight = Math.abs(_y - startY)
                                if (_x - startX < 0) {
                                    // console.log('向左拉')
                                    newLeft = Math.min(_x, startX)-left
                                    // selDiv.style.left = l + "px";
                                    //向边框右方对齐 改 width
                                    newWidth = (parseInt((posX - spanX)/oneW) + 1) * oneW + spanX - newLeft
                                } else {
                                    // 向边框左方对齐
                                    newLeft = (parseInt((posX - spanX)/oneW)) * oneW + spanX
                                    // console.log(posX, oneW,  parseInt((l - spanX)/oneW), 'desc', l)
                                }
                                if (_y - startY < 0) {
                                    // console.log('向上拉 改 height')
                                    newTop = Math.min(_y, startY)-top + spanY 
                                    // selDiv.style.top = Math.min(_y, startY)-top + spanY + "px";
                                    // 向边框下方对齐
                                    newHeight = (parseInt((posY - spanY)/oneH) + 1) * oneH + spanY - newTop
                                } else {
                                    // 向边框上方对齐
                                    newTop = (parseInt((posY - spanY)/oneH)) * oneH + spanY
                                    // console.log(posY, oneH,  parseInt((l - spanX)/oneH), 'desc', l)
                                }
                                selDiv.style.left = newLeft + "px";
                                selDiv.style.top = newTop + "px";
                                selDiv.style.width = newWidth + "px";
                                selDiv.style.height = newHeight + "px";

                            }
                            vnode.context.clearEventBubble(evt);
                        };
                        //方法是确定列表到屏幕的位置
                        function getX(obj){
                            var parObj=obj;
                            var left=0 ;//obj.offsetLeft;
                            while(parObj){
                                left+=parObj.offsetLeft;
                                parObj=parObj.offsetParent
                            }
                            return left;
                        }
                        //方法是确定列表到屏幕的位置
                        function getY(obj){
                            var parObj=obj;
                            var top=0 //obj.offsetTop;
                            while(parObj){
                                top+=parObj.offsetTop;
                                parObj = parObj.offsetParent
                            }
                            return top;
                        }
                        //在鼠标抬起后做的重置
                        document.onmouseup = function () {
                            //把鼠标移动事初始化
                            document.onmousemove=null;
                            if (selDiv && document.getElementById('selectDiv')) {
                                // 取选中
                                var left = selDiv.offsetLeft
                                var top = selDiv.offsetTop
                                var width = selDiv.offsetWidth
                                var height = selDiv.offsetHeight
                                // console.log(left, top, width, height)
                                // 计算鼠标按下点是否为选中状态 
                                let oneW = fileNodes[1].offsetWidth
                                let oneH = fileNodes[1].offsetHeight

                                // oDiv.querySelectorAll('.selectTimeBlock').forEach(ele => {
                                //     ele.style.height = oneH + 'px'
                                // })


                                let isSelect = true
                                // let clickLeft = (parseInt((posX - spanX)/oneW)) * oneW + spanX
                                //     // left = posX
                                // let clickTop = (parseInt((posY - spanY)/oneH)) * oneH + spanY
                                // console.log(left, top, clickLeft, clickTop)
                                for (let i = 0; i < fileNodes.length; i++) {
                                    let data = fileNodes[i].getAttribute('data')
                                    if (!data) {
                                        continue
                                    }
                                    let l = fileNodes[i].offsetLeft
                                    let t = fileNodes[i].offsetTop
                                    // console.log('data', data,'oneW',oneW, 'oneH',oneH,'pos:', posX, posY,'area', l, t)
                                    if (posX >= l && posX < l + oneW && posY>= t && posY< t + oneH) {
                                        // console.log('click data', data)
                                        let idx = vnode.context.multipleSelection.findIndex((e) => {
                                            return e == data
                                        })
                                        isSelect = idx == -1
                                        break
                                    }
                                }

                                if (width == 0 && height == 0) {
                                    // 认为是点击
                                    // console.log('认为是点击')
                                    left = (parseInt((posX - spanX)/oneW)) * oneW + spanX
                                    // left = posX
                                    top = (parseInt((posY - spanY)/oneH)) * oneH + spanY
                                    // top = posY
                                    width = 2
                                    height = 2
                                } else {
                                    // 修正到线上
                                    if ((left - spanX)%oneW > 2) {
                                        // console.log('修正到线上X')
                                        left = (parseInt((left - spanX)/oneW)) * oneW + spanX
                                    }
                                    if ((top - spanY)%oneH > 2) {
                                        // console.log('修正到线上Y')
                                        top = (parseInt((top - spanY)/oneH)) * oneH + spanY
                                    }
                                }
                                for (let i = 0; i < fileNodes.length; i++) {
                                    let data = fileNodes[i].getAttribute('data')
                                    if (!data) {
                                        continue
                                    }
                                    let l = fileNodes[i].offsetLeft + 1
                                    let t = fileNodes[i].offsetTop + 1
                                    // var sl = fileNodes[i].offsetWidth + fileNodes[i].offsetLeft;
                                    // var st = fileNodes[i].offsetHeight + fileNodes[i].offsetTop;
                                    if (l >= left && l <= left + width && t>= top && t<= top + height) {
                                        // console.log(left, top, 'rect',  l, t,'数据', fileNodes[i].getAttribute('x'), fileNodes[i].getAttribute('y'))
                                        let idx = vnode.context.multipleSelection.findIndex((e) => {
                                            return e == data
                                        })
                                        if (isSelect) {
                                            // fileNodes[i].setAttribute('class', 'selected')
                                            if (idx == -1) {
                                                vnode.context.multipleSelection.push(data)
                                            }
                                        } else {
                                            // fileNodes[i].removeAttribute('class')
                                            let idx = vnode.context.multipleSelection.findIndex((e) => {
                                                return e == data
                                            })
                                            if (idx > -1) {
                                                vnode.context.multipleSelection.splice(idx,1);
                                            }
                                        }
                                        // selList.push(fileNodes[i])
                                    }
                                }
                                document.getElementsByClassName("calendar-body")[0].removeChild(selDiv);
                            }
                            _x = null, _y = null, startX = null, startY = null, evt = null;
                            vnode.context.mouseflag = false;
                            vnode.context.$handleSelect();
                        };
                    };
                }
            }
        },
        data() {
            return {
                multipleSelection: [],
                hours: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23],
                times: [{
                        id: '1',
                        week: '星期一',
                        atoms: atomdata
                    },
                    {
                        id: '2',
                        week: '星期二',
                        atoms: atomdata
                    },
                    {
                        id: '3',
                        week: '星期三',
                        atoms: atomdata
                    },
                    {
                        id: '4',
                        week: '星期四',
                        atoms: atomdata
                    },
                    {
                        id: '5',
                        week: '星期五',
                        atoms: atomdata
                    },
                    {
                        id: '6',
                        week: '星期六',
                        atoms: atomdata
                    },
                    {
                        id: '7',
                        week: '星期日',
                        atoms: atomdata
                    },
                ],
            }
        },
        watch: {
            schedule_time: {
                immediate: true, // 很重要！！！
                handler () {
                    if (this.schedule_time && this.schedule_time.length == COLUMN_COUNT *7) {
                        // console.log('input schedule_time', this.schedule_time)
                        let val = this.schedule_time.split('')
                        for (let i = 0; i < val.length; i++) {
                            if (val[i] == '1') {
                                if (this.multipleSelection.findIndex(e => e == i) == -1) {
                                    this.multipleSelection.push(i)
                                }
                            }
                        }
                    }
                }
            }
        },
        mounted() {
        },
        computed: {
            schedule: function() {
                let val = []
                for (let i = 0; i < COLUMN_COUNT * 7; i++) {
                    let t = this.multipleSelection.find(e => {
                        return e == i
                    })
                    val.push(t ? 1 : 0)
                }
                return val.join('')
            },
            selecTimes: function() {
                let datas = this.multipleSelection.slice(0)
                datas = datas.sort((a, b) => {
                    return a - b
                })
                let result = []
                datas.forEach(e => {
                    let id = parseInt(e / COLUMN_COUNT)
                    let pos = e % COLUMN_COUNT + 1
                    let ele = result.find( ele => {
                        return ele.id == id
                    })
                    if (ele) {
                        ele.times.push(pos)
                    } else {
                        result.push({id: id, weeks: WEEKS[id], times: [pos], points:[]})
                    }
                })
                // 对时间点进行处理
                result.forEach(ele => {
                    let stime = ele.times[0]
                    let etime = ele.times[0]
                    let pos = 0
                    
                    for (let i = 0; i < ele.times.length; i++) {
                        if (stime + pos == ele.times[i]) {
                            etime = ele.times[i]
                            pos = pos + 1
                        } else {
                            ele.points.push({time: this.formatTime(stime , etime) })
                            stime = ele.times[i]
                            etime = ele.times[i]
                            pos = 1
                        }
                    }
                    ele.points.push({time: this.formatTime(stime , etime)})
                })
                return result
            }
        },
        methods: {
            formatTip(id, pos) {
                
                return WEEKS[id - 1] + ' ' + this.formatTime(pos)
            },
            formatTime(stime, etime) {
                if (stime > COLUMN_COUNT) {
                    stime = stime % COLUMN_COUNT
                }
                let s = (stime-1) * 30
                let e = (etime * 30)
                const formatObj1 = {
                    h: parseInt(s / 60),
                    i: s % 60
                }
                let time_str = this._format(formatObj1)
                if (!etime) {
                    return time_str
                }
                const formatObj2 = {
                    h: parseInt(e / 60),
                    i: e % 60
                }
                time_str = time_str + '~' + this._format(formatObj2)
                // console.log(time_str)
                return time_str
            },
            _format(formatObj) {
                const format = '{h}:{i}'
                const time_str = format.replace(/{([hi])+}/g, (result, key) => {
                    const value = formatObj[key]
                    return value.toString().padStart(2, '0')
                })
                return time_str
            },
            //清除默认事件
            clearEventBubble(evt) {
                if (evt.stopPropagation)
                    evt.stopPropagation();
                else
                    evt.cancelBubble = true;
                if (evt.preventDefault)
                    evt.preventDefault();
                else
                    evt.returnValue = false;
            },
            //当批量选中结束调用
            $handleSelect(){
                this.$emit('change',this.schedule)
            },
            isSelect(x, y) {
                let data = this.getData(x, y)
                let idx = this.multipleSelection.findIndex(ele => {
                    return ele == data
                })
                return idx == -1 ? '' : 'selected'
            },
            getData(x, y) {
                x--
                y--
                // console.log(x, y)
                return x * atomdata.length + y
            },
            clear() {
                this.multipleSelection = []
                this.$handleSelect()
            }
        }
    }
</script>
